home *** CD-ROM | disk | FTP | other *** search
- #include "video.hpp"
-
- // Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
-
- unsigned char *LookPal; // Linear palette
- unsigned char *LookPalPhong; // Phong palette (phong illumination model)
-
- unsigned char *TransTBL;
- unsigned char *HazeTBL;
- int *PhongTBL; // holds angles.
- int *TextureMap;
-
- int SCREENWIDTH;
- int SCREENHEIGHT;
- int SCREENSIZE;
- int HALF_SCREEN_WIDTH;
- int HALF_SCREEN_HEIGHT;
- int ASPECT_SCREEN_HEIGHT;
- int YON_Z;
- int HITHER_Z;
-
- float HALF_SCREEN_WIDTH_VD;
- float HALF_SCREEN_HEIGHT_VD;
- float SCANLINELENGTH;
-
- int GetMode(void);
- #pragma aux GetMode =\
- "mov ah,0x0F",\
- "int 0x10,"\
- "and eax,0xFF",\
-
- int SetMode(int);
- #pragma aux SetMode =\
- "int 0x10",\
- parm [eax]\
-
- void ZapBuff(unsigned char *Dest,unsigned char *Source,int Count);
- #pragma aux ZapBuff =\
- "rep movsd"\
- modify [edi esi ecx]\
- parm [edi] [esi] [ecx]\
- ;
-
- VIDEOCLASS::VIDEOCLASS(void) // Constructor
- {
- VidMem=(unsigned char *)0xa0000; // pointer to VidMem.
- pcx = new PcxFile;
- memset (pcx,'\0',sizeof(PcxFile)); // clear
-
- Background=NULL;
- VideoBuffer=NULL;
- TransTBL=NULL;
- PhongTBL=NULL;
- TextureMap=NULL;
- LookPal=NULL;
- LookPalPhong=NULL;
- }
-
- VIDEOCLASS::~VIDEOCLASS(void) // Destructor.
- {
- if (pcx != NULL)
- {
- if (pcx->bitmap != NULL)
- delete pcx->bitmap;
- delete pcx;
- }
- if (VideoBuffer != NULL)
- delete VideoBuffer;
- if (Background != NULL)
- delete Background;
- if (TransTBL != NULL)
- delete TransTBL;
- if (PhongTBL != NULL)
- delete PhongTBL;
- if (HazeTBL != NULL)
- delete HazeTBL;
- if (TextureMap != NULL)
- delete TextureMap;
- if (LookPal != NULL) // linear palette.
- delete LookPal;
- if (LookPalPhong != NULL) // conforms to Phong illumination model.
- delete LookPalPhong;
-
- SetMode(prevmode);
- }
-
- void VIDEOCLASS::InitVideo(int Mode)
- {
- prevmode = GetMode(); // get previous mode.
-
- switch (Mode)
- {
- case MCGA_320_200_256:
- SetMode(0x13);
-
- _ScreenWidth = SCREENWIDTH = 320;
- SCREENHEIGHT = 200;
- SCREENSIZE = SCREENWIDTH*SCREENHEIGHT;
-
- HALF_SCREEN_WIDTH = SCREENWIDTH/2;
- HALF_SCREEN_HEIGHT = SCREENHEIGHT/2;
- ASPECT_SCREEN_HEIGHT = 125; // (6/5)*(200/2);
- HALF_SCREEN_WIDTH_VD = (float)HALF_SCREEN_WIDTH/(float)VIEWDISTANCE;
- HALF_SCREEN_HEIGHT_VD = (float)ASPECT_SCREEN_HEIGHT/(float)VIEWDISTANCE;
- SCANLINELENGTH = (float)1/(float)SCREENWIDTH;
-
- _MinClipX = 10;
- _MinClipY = 10;
- _MaxClipX = 310;
- _MaxClipY = 190;
-
- MEMSIZE=64000;
- break;
-
- case SVGA_640_480_256: // note: SVGA or mode other than 0x13
- SetMode(0x101); // hasn't been implemented yet. DOH!
-
- _ScreenWidth = SCREENWIDTH = 640;
- SCREENHEIGHT = 480;
- SCREENSIZE = SCREENWIDTH*SCREENHEIGHT;
-
- HALF_SCREEN_WIDTH = SCREENWIDTH/2;
- HALF_SCREEN_HEIGHT = SCREENHEIGHT/2;
- ASPECT_SCREEN_HEIGHT = 240; // no need to adjust by aspect ratio.
- HALF_SCREEN_WIDTH_VD = (float)HALF_SCREEN_WIDTH/(float)VIEWDISTANCE;
- HALF_SCREEN_HEIGHT_VD = (float)ASPECT_SCREEN_HEIGHT/(float)VIEWDISTANCE;
- SCANLINELENGTH = (float)1/(float)SCREENWIDTH;
-
- _MinClipX = 10;
- _MinClipY = 10;
- _MaxClipX = 630;
- _MaxClipY = 470;
-
- MEMSIZE=307200;
- break;
- default:
- Error("Couldn't find Video Mode\n");
- break;
- }
- }
-
- void VIDEOCLASS::SetClipExtents(int XMinClip,int YMinClip,int XMaxClip,int YMaxClip,
- int HitherClip,int YonClip)
- {
- _MinClipX=XMinClip;
- _MinClipY=YMinClip;
- _MaxClipX=XMaxClip;
- _MaxClipY=YMaxClip;
- HITHER_Z=HitherClip;
- YON_Z=YonClip;
- }
-
- unsigned char *VIDEOCLASS::LoadPcxFile(char *filename)
- {
- unsigned long int i;
- short int mode=NORMAL,nbytes;
- unsigned char abyte,*p;
- FILE *fptr;
-
- fptr=fopen(filename,"rb");
- if (fptr==NULL)
- Error("Couldn't Load PCX file\n");
-
- fread(&pcx->hdr,sizeof(PcxHeader),1,fptr);
- pcx->width=(short int)(1+pcx->hdr.xmax-pcx->hdr.xmin);
- pcx->height=(short int)(1+pcx->hdr.ymax-pcx->hdr.ymin);
- pcx->imagebytes=pcx->width*pcx->height;
- PcxSize = pcx->imagebytes;
- if (pcx->bitmap != NULL)
- delete pcx->bitmap;
- pcx->bitmap=new unsigned char [ sizeof(char)*pcx->imagebytes ];
- if (pcx->bitmap==NULL)
- Error("Not enough memory\n");
-
- p=pcx->bitmap;
- for(i=0;i<pcx->imagebytes;i++)
- {
- if(mode == NORMAL)
- {
- abyte=(unsigned char)fgetc(fptr);
- if(( unsigned char )abyte > 0xbf)
- {
- nbytes=(short int)(abyte & 0x3f);
- abyte=(unsigned char)fgetc(fptr);
- if(--nbytes > 0)
- mode=RLE;
- }
- }
- else if(--nbytes == 0)
- mode=NORMAL;
- *p++=(unsigned char)abyte;
- }
-
- fseek(fptr,-768L,SEEK_END); // get palette from pcx file
- fread(pcx->pal,768,1,fptr);
- p=pcx->pal;
- for(i=0;i<768;i++) // bit shift palette
- *p++=*p>>2;
- fclose(fptr);
-
- return (pcx->bitmap); // return pointer to bitmap.
- }
-
- ImageStats *VIDEOCLASS::GetStats(void)
- {
-
- Stats.width = pcx->width;
- Stats.height = pcx->height;
- Stats.size = pcx->imagebytes;
-
- return (&Stats);
- }
-
- void VIDEOCLASS::SetAllRgbPalette(void) // Use pcx->palette.
- {
- struct SREGS s;
- union REGS r;
-
- memset(VidMem,0,MEMSIZE); // clear VideoMemory (So nothing shows when palette is changed).
- memcpy(CurrentPalette,pcx->pal,768); // save current palette.
-
- segread(&s); // get current segment values
- s.es=FP_SEG((void far*)pcx->pal); // point ES to pal array
- r.x.edx=FP_OFF((void far*)pcx->pal); // get offset to pal array
- r.x.eax=0x1012; // BIOS func 10h sub 12h
- r.x.ebx=0; // starting DAC register
- r.x.ecx=256; // ending DAC register
- int386x(0x10,&r,&r,&s); // call video BIOS
- }
-
- void VIDEOCLASS::SetPaletteArg(unsigned char *pal) // Set specific palette.
- {
- struct SREGS s;
- union REGS r;
-
- segread(&s); // get current segment values
- s.es=FP_SEG((void far*)pal); // point ES to pal array
- r.x.edx=FP_OFF((void far*)pal); // get offset to pal array
- r.x.eax=0x1012; // BIOS func 10h sub 12h
- r.x.ebx=0; // starting DAC register
- r.x.ecx=256; // ending DAC register
- int386x(0x10,&r,&r,&s); // call video BIOS
- }
-
- void VIDEOCLASS::CreateRGBPalette(void)
- {
- int index;
-
- for (index=0; index<64; index++)
- {
- outp(COLOR_REGISTER_WR, index);
-
- outp(COLOR_DATA,index);
- outp(COLOR_DATA,index);
- outp(COLOR_DATA,index);
-
- outp(COLOR_REGISTER_WR, index+64);
-
- outp(COLOR_DATA,index);
- outp(COLOR_DATA,0);
- outp(COLOR_DATA,0);
-
- outp(COLOR_REGISTER_WR, index+128);
-
- outp(COLOR_DATA,0);
- outp(COLOR_DATA,index);
- outp(COLOR_DATA,0);
-
- outp(COLOR_REGISTER_WR, index+192);
-
- outp(COLOR_DATA,0);
- outp(COLOR_DATA,0);
- outp(COLOR_DATA,index);
- }
- }
-
- void VIDEOCLASS::FadeToBlack(void)
- {
- int index,index2;
- unsigned char Red,Green,Blue;
-
- for (index2=0; index2<30; index2++) // probably good enough to cycle colors.
- {
- for (index=0; index<256; index++)
- {
- outp(COLOR_REGISTER_RD, index);
-
- Red=(unsigned char)inp(COLOR_DATA);
- Green=(unsigned char)inp(COLOR_DATA);
- Blue=(unsigned char)inp(COLOR_DATA);
-
- if (Red<5)
- Red=0;
- else
- Red-=3;
-
- if (Green<5)
- Green=0;
- else
- Green-=3;
-
- if (Blue<5)
- Blue=0;
- else
- Blue-=3;
-
- outp(COLOR_REGISTER_WR, index);
-
- outp(COLOR_DATA,Red);
- outp(COLOR_DATA,Green);
- outp(COLOR_DATA,Blue);
- }
- WaitFor(1);
- }
- }
-
- void VIDEOCLASS::FadeToColor(void)
- {
- int index,index2,colorindex;
- unsigned char Palette[768];
-
- memset(Palette,0,768); // make it black.
- SetPaletteArg(Palette);
- Buf2Video(); // put to screen.
-
- for (index2=0; index2<30; index2++) // probably good enough to cycle colors.
- {
- colorindex=0;
- for (index=0; index<256; index++)
- {
- outp(COLOR_REGISTER_WR, index);
-
- if ( Palette[colorindex] >= CurrentPalette[colorindex] )
- Palette[colorindex]=CurrentPalette[colorindex];
- else
- Palette[colorindex]+=3;
-
- outp(COLOR_DATA,Palette[colorindex++]);
-
- if ( Palette[colorindex] >= CurrentPalette[colorindex] )
- Palette[colorindex]=CurrentPalette[colorindex];
- else
- Palette[colorindex]+=3;
-
- outp(COLOR_DATA,Palette[colorindex++]);
-
- if ( Palette[colorindex] >= CurrentPalette[colorindex] )
- Palette[colorindex]=CurrentPalette[colorindex];
- else
- Palette[colorindex]+=3;
-
- outp(COLOR_DATA,Palette[colorindex++]);
- }
- WaitFor(2);
- }
- }
-
- void VIDEOCLASS::LoadPalTable(char *filename)
- {
-
- FILE *fptr;
- char tname[30],buffer[30];
- unsigned char *texture;
-
- fptr=fopen(filename,"rb");
- if (fptr==NULL)
- Error("Couldn't Load Palette\n");
-
- fread((void *)buffer,sizeof(char),8,fptr); // header.
- fscanf(fptr,"%4d",&Shades); // num of shades.
-
- LookPal = new unsigned char [ sizeof(char)*Shades*256 ]; // allocate a giant lookup for palette.
- if (LookPal==NULL)
- Error("Not enough memory\n");
-
- fread((void *)buffer,sizeof(char),12,fptr); // header.
- fread((void *)buffer,sizeof(char),30,fptr);
-
- fread((void *)LookPal,sizeof(unsigned char),Shades*256,fptr);
-
- fclose(fptr);
-
- if (TextureMap == NULL) // Texturemap not loaded, so use the texture, the palette was originally made from.
- {
-
- strcpy(tname,"images/"); // prefix it with path.
- strcat(tname,buffer);
- texture=LoadPcxFile(tname);
- SetAllRgbPalette();
-
- TextureMap = new int [ sizeof(int)*PcxSize ]; // allocate Texture map.
- if (TextureMap==NULL)
- Error("Not enough memory\n");
-
- int index;
-
- for (index=0;index<PcxSize;index++) // premultiply by num shades so i'll get correct offset in table.
- {
- TextureMap[index] = texture[index]*Shades;
- }
- }
-
- _LookPAL = LookPal; // let polylow.asm have access to it.
- }
-
- void VIDEOCLASS::LoadPalPhongTable(char *filename)
- {
-
- FILE *fptr;
- char tname[30],buffer[30];
- unsigned char *texture;
-
- // NOTE: with Phong illumination model applied to palette. Gouraud and
- // Phong look very similar at a glance. But intensities for Gouraud are
- // linear while intensity shading of Phong is not.
-
- fptr=fopen(filename,"rb");
- if (fptr==NULL)
- Error("Couldn't Load Palette\n");
-
- fread((void *)buffer,sizeof(char),8,fptr); // header.
- fscanf(fptr,"%4d",&Shades); // num of shades.
-
- LookPalPhong = new unsigned char [ sizeof(char)*Shades*256 ]; // allocate a giant lookup for palette.
- if (LookPalPhong==NULL)
- Error("Not enough memory\n");
-
- fread((void *)buffer,sizeof(char),12,fptr); // header.
- fread((void *)buffer,sizeof(char),30,fptr);
-
- fread((void *)LookPalPhong,sizeof(unsigned char),Shades*256,fptr);
-
- fclose(fptr);
-
- if (TextureMap == NULL) // Texturemap not loaded, so use the texture, the palette was originally made from.
- {
-
- strcpy(tname,"images/"); // prefix it with path.
- strcat(tname,buffer);
- texture=LoadPcxFile(tname);
- SetAllRgbPalette();
-
- TextureMap = new int [ sizeof(int)*PcxSize ]; // allocate Texture map.
- if (TextureMap==NULL)
- Error("Not enough memory\n");
-
- int index;
-
- for (index=0;index<PcxSize;index++) // premultiply by num shades so i'll get correct offset in table.
- {
- TextureMap[index] = texture[index]*Shades;
- }
- }
- }
-
- void VIDEOCLASS::LoadTextureMap(char *filename)
- {
- unsigned char *texture;
-
- texture=LoadPcxFile(filename);
- SetAllRgbPalette();
-
- TextureMap = new int [ sizeof(int)*PcxSize ]; // allocate Texture map.
- if (TextureMap==NULL)
- Error("Not enough memory\n");
-
- int index;
-
- for (index=0;index<PcxSize;index++) // premultiply by num shades so i'll get correct offset in table.
- {
- TextureMap[index] = texture[index]*64; // default to 64 shades.
- }
- }
-
- int VIDEOCLASS::LoadTransTable(char *filename)
- {
- FILE *fptr;
- char tname[30],buffer[30];
- int numread, Levels;
-
- fptr=fopen(filename,"rb");
- if (fptr==NULL)
- Error("Unable to Load Transparency Table\n");
-
- numread=fread((void *)buffer,sizeof(char),19,fptr); // header.
- numread=fscanf(fptr,"%2d",&Levels);
-
- TransTBL = new unsigned char [ sizeof(char)*256*256*Levels ]; // allocate a giant trans lookup.
- if (TransTBL==NULL)
- Error("Not enough memory\n");
-
- numread=fread((void *)buffer,sizeof(char),12,fptr); // header.
- numread=fread((void *)tname,sizeof(char),30,fptr);
- numread=fread((void *)TransTBL,sizeof(unsigned char),256*256*Levels,fptr); // load in table.
-
- fclose(fptr);
-
- return (Levels-1); // we don't want fully transparent.
- }
-
- void VIDEOCLASS::LoadHazeTable(char *filename)
- {
- FILE *fptr;
- char buffer[30];
- char texture[30];
- int Levels;
-
- fptr=fopen(filename,"rb");
-
- fread((void *)buffer,sizeof(char),11,fptr); // header.
- fscanf(fptr,"%4d",&Levels);
-
- HazeTBL = new unsigned char [ sizeof(char)*256*Levels ]; // allocate a giant haze lookup.
- if (HazeTBL==NULL)
- Error("Not enough memory\n");
-
- fread((void *)buffer,sizeof(char),12,fptr); // header.
- fread((void *)texture,sizeof(char),30,fptr);
- fread((void *)HazeTBL,sizeof(unsigned char),256*Levels,fptr); // load in table.
-
- fclose(fptr);
- }
-
- void VIDEOCLASS::LoadPhongTBL(char *filename) // holds precomputed angles.
- {
- FILE *fptr;
- char buffer[30];
-
- PhongTBL = new int [ sizeof(int)*90*256 ]; // for 90 degrees in fixed point 8.
- if (PhongTBL==NULL)
- Error("Not enough memory\n");
-
- fptr=fopen(filename,"rb");
- if (fptr==NULL)
- Error("Couldn't load PHONG table\n");
-
- fread((void *)buffer,sizeof(char),13,fptr); // header.
- fread((void *)PhongTBL,sizeof(int),90*256,fptr); // load in table.
-
- fclose(fptr);
- }
-
- unsigned char *VIDEOCLASS::CreateBuffer(int color)
- {
- VideoBuffer = new unsigned char[ sizeof(char)*MEMSIZE ]; // we know how big, by what video mode we're in.
- //VideoBuffer=(unsigned char *)0xa0000; // for Debug purposes. Set if want ouput directly to screen. ( Rem the line above first. )
-
- if (VideoBuffer==NULL)
- Error("not enough memory for VideoBuffer\n");
-
- bgcolor=color; // color to clear buffer with.
-
- _RendBuffer=VideoBuffer; // let polylow.asm have access to buffer.
- return (VideoBuffer);
- }
-
- void VIDEOCLASS::ClearBuffer(void)
- {
- if (Background != NULL) // if there is a background loaded, use it.
- memcpy(VideoBuffer,Background,MEMSIZE);
- else
- memset(VideoBuffer,bgcolor,MEMSIZE);
- }
-
- void VIDEOCLASS::Buf2Video(void)
- {
- ZapBuff(VidMem,VideoBuffer,MEMSIZE>>2); // dwords at a time.
- }
-
- void VIDEOCLASS::LoadBackground(char *filename)
- {
-
- if (Background != NULL)
- delete Background;
-
- Background = new unsigned char [ sizeof(char)*MEMSIZE ];
- if (Background==NULL)
- Error("not enough memory\n");
-
- unsigned char *bitmap;
- bitmap=LoadPcxFile(filename);
-
- memcpy(Background,bitmap,MEMSIZE);
- memcpy(VideoBuffer,Background,MEMSIZE);
- }
-
- void VIDEOCLASS::DeleteBackground(void)
- {
- if (Background != NULL)
- {
- delete Background;
- Background=NULL;
- }
- }
-
- unsigned char *VIDEOCLASS::GetBuffer(void)
- {
- return (VideoBuffer);
- }
-
-